package org.imsoss.refpoint.gm;

import java.util.ArrayList;
import java.util.ListIterator;

import org.apache.log4j.Logger;

import javax.sip.ClientTransaction;
import javax.sip.SipProvider;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.address.URI;
import javax.sip.header.CSeqHeader;
import javax.sip.header.CallIdHeader;
import javax.sip.header.FromHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.header.RouteHeader;
import javax.sip.header.MaxForwardsHeader;
import javax.sip.header.ToHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Message;

import org.imsoss.refpoint.ReferencePoint;
//import org.imsoss.refpoint.ImsMessages;
import org.imsoss.util.ImsConfiguration;


public class GmReferencePoint extends ReferencePoint
{
	public static String UEBRANCH;
	SipProvider provider;
	AddressFactory addressFactory;
	HeaderFactory headerFactory;
	MessageFactory messageFactory;
	
	public GmReferencePoint(SipProvider provider, AddressFactory addressFactory, HeaderFactory headerFactory, MessageFactory messageFactory)
	{		
		this.provider = provider;
		this.addressFactory = addressFactory;
		this.headerFactory = headerFactory;
		this.messageFactory = messageFactory;
	}
	
	/*
	 *  This is registration procedure 
	 */
	public void processOnRegister(Request request)
	{
		//System.out.println("[1.1] Trigerring the GmReferencePoint ");
		// The SIP message should be diverted to the I-CSCF node from here, the I-CSCF node will be running on 5070 port.
		try
		{
			Request registerForIcscf = request;
			// The rfc3261 says : When UAC creates a request, it *MUST* insert a Via into the request.
			// We will add Via p-cscf: 127.0.0.1:5070
			ListIterator<ViaHeader> iter = request.getHeaders(ViaHeader.NAME);
			while(iter.hasNext()){
				ViaHeader viaHeader = iter.next();
				if(viaHeader.getPort() == ImsConfiguration.pcscfPort) // Indicates that the SIP messages has passed P-CSCF.
				{
					//System.out.println("SIP message appearing from P-CSCF/I-CSCF/S-CSCF, no action over here");
					return;
				}
				//System.out.println("--------------->>>>:::"+viaHeader.getHost()+":"+viaHeader.getPort());
			}
			System.out.println("[1]   This is the entry point of the P-CSCF of the imsoss \n"+request);
			System.out.println("[1.1] Trigerring the GmReferencePoint "+request.getRequestURI());
			// Going to Generate the SIP REGISTER message to I-CSCF.
			System.out.println("[2]SIP message are going to passed to I-CSCF now ");
			// peerHostPort is the IP address where the REGISTER MESSAGE should go.
			//String peerHostPort = "127.0.0.1:6080";
			String peerHostPort = ImsConfiguration.icscfAddress+":"+ImsConfiguration.icscfPort;
			/*
			 * DNS lookup should happen on peerHost(ImsConfiguration.icscfAddress), icscfAddress could be icscf.com.
			 * InetAddress resolver = InetAddress.getByName(ImsConfiguration.icscfAddress);
			 * String resolvedAddress = resolver.getHostAddress();
			 * peerHostPort = resolvedAddress+":"+ImsConfiguration.icscfPort;
			 */
			FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME);
			
			ToHeader toHeader = (ToHeader)request.getHeader(ToHeader.NAME);
			String toUser = toHeader.getName();
			String toDisplayName = toHeader.getAddress().getDisplayName();
			//System.out.println("toDisplayName ::::: "+toDisplayName);
						
			URI requestURI = request.getRequestURI();//addressFactory.createSipURI(toDisplayName,peerHostPort);

			CallIdHeader callIdHeader = provider.getNewCallId();
			CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L,Request.REGISTER);

			ArrayList viaHeaders = new ArrayList();
			String ipAddress = "127.0.0.1";
			// Adding the P-CSCF info in the VIA header.....
			
			ViaHeader viaHeaderr = (ViaHeader)request.getHeader(ViaHeader.NAME);
			//System.out.println("brach header is "+viaHeaderr.getBranch());
			
			ViaHeader viaHeader = headerFactory.createViaHeader(ipAddress,ImsConfiguration.pcscfPort,"udp",null);
			viaHeaders.add(viaHeader);
			viaHeader = headerFactory.createViaHeader(ipAddress,5061,"udp",viaHeaderr.getBranch());
			UEBRANCH = viaHeaderr.getBranch();
			viaHeaders.add(viaHeader);
			
			// Create a new MaxForwardsHeader
			MaxForwardsHeader maxForwards = headerFactory.createMaxForwardsHeader(70);
			Request pcscfRequest = messageFactory.createRequest(requestURI,
					Request.REGISTER, callIdHeader, cSeqHeader, fromHeader,
					toHeader, viaHeaders, maxForwards);			
			// Adding Route Header here, this will basically decide where the SIP message should be dispatched next....
			Address address = addressFactory.createAddress("sip:"+peerHostPort);			
			RouteHeader routeHeader = headerFactory.createRouteHeader(address);
			
			pcscfRequest.addHeader(routeHeader);
			
			System.out.println("------------->>>>> \n"+pcscfRequest);
			ClientTransaction registerTid = provider.getNewClientTransaction(pcscfRequest);		
			// The sendRequest should be the part of the MwReferencePoint
						
			registerTid.sendRequest(); 
		}
		catch(Exception e){
			logger.error("Error Appearing from onRegister() ");
			e.printStackTrace();
		}
	}

	
	public void processOnInvite(){
		
	}
	
	public void processOnBye(){
		
	}
	
	public void processOnMessage(){
		
	}
	
	public void processOtherSipMessage(){
		
	}
	
	public void compressSip(){
		
	}
	private static final Logger logger = Logger.getLogger(GmReferencePoint.class);
}